package projects

import (
	"github.com/beego/beego/v2/client/orm"
	beego "github.com/beego/beego/v2/server/web"
	"strconv"
	"time"
	"xpms/app/models"
	"xpms/cores"
	"xpms/cores/utils"
)

type ProjectsNeeds struct {
	Id          int64 `orm:"pk;column(needsid);" json:"Id,string"`
	Type        int
	Projectid   int64 `json:"Projectid,string"`
	Userid      int64 `json:"Userid,string"`
	Name        string
	Desc        string
	Acceptid    int64 `json:"Acceptid,string"`
	Source      int
	Acceptance  string
	Level       int
	Tasktime    int
	Attachment  string
	Created     int64
	Changed     int64
	Stage       int
	Status      int
	Xcoordinate float64
	Ycoordinate float64
	Colour      string
	Pneedsid    int64 `json:"pneedsid,string"`
	Orders      int
	Crosswise   int64 `json:"Crosswise,string"`
	Lengthways  int64 `json:"Lengthways,string"`
	High        int
	Width       int
}

type ProjectsPageeNeeds struct {
	Id          int64 `json:"Id,string"`
	Projectid   int64 `json:"Projectid,string"`
	Userid      int64 `json:"Userid,string"`
	Type        int
	Name        string
	Desc        string
	Acceptid    int64 `json:"Acceptid,string"`
	Source      int
	Acceptance  string
	Level       int
	Tasktime    int
	Attachment  string
	Created     int64
	Changed     int64
	Stage       int
	Status      int
	Username    string
	Acceptname  string
	Xcoordinate float64
	Ycoordinate float64
	Colour      string
	Pneedsid    int64 `json:"Pneedsid,string"`
	Orders      int
	Crosswise   int64 `json:"Crosswise,string"`
	Lengthways  int64 `json:"Lengthways,string"`
	High        int
	Width       int
}

func (this *ProjectsNeeds) TableName() string {
	return models.TableName("projects_needs")
}
func init() {
	orm.RegisterModel(new(ProjectsNeeds))
}

func AddNeeds(userid int64, upd NeedsDTO) error {
	o := orm.NewOrm()
	needs := new(ProjectsNeeds)
	//雪花算法ID生成
	id := utils.SnowFlakeId()
	utils.SimpleCopyProperties(needs, upd)
	needs.Id = id
	needs.Userid = userid
	needs.Changed = time.Now().Unix()
	needs.Created = time.Now().Unix()
	_, err := o.Insert(needs)
	return err
}

func UpdateNeeds(id int64, upd ProjectsNeeds) error {
	var needs ProjectsNeeds
	o := orm.NewOrm()
	needs.Changed = time.Now().Unix()
	needs.Id = id
	var col []string
	col = append(col, "changed")
	if !utils.IsEmpty(upd.Name) {
		needs.Name = upd.Name
		col = append(col, "name")
	}
	if !utils.IsEmpty(upd.Desc) {
		needs.Desc = upd.Desc
		col = append(col, "desc")
	}
	if !utils.IsEmpty(upd.Acceptid) {
		needs.Acceptid = upd.Acceptid
		col = append(col, "acceptid")
	}
	if !utils.IsEmpty(upd.Source) {
		needs.Source = upd.Source
		col = append(col, "source")
	}
	if !utils.IsEmpty(upd.Acceptance) {
		needs.Acceptance = upd.Acceptance
		col = append(col, "acceptance")
	}
	if !utils.IsEmpty(upd.Level) {
		needs.Level = upd.Level
		col = append(col, "level")
	}
	if !utils.IsEmpty(upd.Tasktime) {
		needs.Tasktime = upd.Tasktime
		col = append(col, "tasktime")
	}
	if !utils.IsEmpty(upd.Stage) {
		needs.Stage = upd.Stage
		col = append(col, "stage")
	}
	if !utils.IsEmpty(upd.Status) {
		needs.Status = upd.Status
		col = append(col, "status")
	}
	if upd.Attachment != "" {
		needs.Attachment = upd.Attachment
		col = append(col, "attachment")
	}
	if !utils.IsEmpty(upd.Xcoordinate) {
		needs.Xcoordinate = upd.Xcoordinate
		col = append(col, "xcoordinate")
	}
	if !utils.IsEmpty(upd.Ycoordinate) {
		needs.Ycoordinate = upd.Ycoordinate
		col = append(col, "ycoordinate")
	}
	if !utils.IsEmpty(upd.Colour) {
		needs.Colour = upd.Colour
		col = append(col, "colour")
	}
	if !utils.IsEmpty(upd.Pneedsid) {
		needs.Pneedsid = upd.Pneedsid
		col = append(col, "pneedsid")
	}
	if !utils.IsEmpty(upd.Orders) {
		needs.Orders = upd.Orders
		col = append(col, "orders")
	}
	if !utils.IsEmpty(upd.Crosswise) {
		needs.Crosswise = upd.Crosswise
		col = append(col, "crosswise")
	}
	if !utils.IsEmpty(upd.Lengthways) {
		needs.Lengthways = upd.Lengthways
		col = append(col, "lengthways")
	}
	if !utils.IsEmpty(upd.High) {
		needs.High = upd.High
		col = append(col, "high")
	}
	if !utils.IsEmpty(upd.Width) {
		needs.Width = upd.Width
		col = append(col, "width")
	}
	_, err := o.Update(&needs, utils.RemoveDuplicatesAndEmpty(col)...)
	return err
}

func GetProjectNeedsByName(name string, projectid int64) ProjectsNeeds {
	var needs ProjectsNeeds
	o := orm.NewOrm()
	err := o.QueryTable(models.TableName("projects_needs")).Filter("name", name).Filter("Projectid", projectid).One(&needs)
	if err == orm.ErrNoRows {
		return needs
	}
	return needs
}

func GetProjectNeeds(id int64) (ProjectsNeeds, error) {
	var needs ProjectsNeeds
	var err error
	o := orm.NewOrm()
	needs = ProjectsNeeds{Id: id}
	err = o.Read(&needs)

	if err == orm.ErrNoRows {
		return needs, nil
	}
	return needs, err
}

func NeedPageExec(condArr map[string]interface{}, page int, offset int) (ops []ProjectsPageeNeeds) {
	o := orm.NewOrm()
	var test []ProjectsPageeNeeds
	o.Raw(NeedPageSql(condArr, 1, page, offset)).QueryRows(&test)
	return test
}

func NeedPageCountExec(condArr map[string]interface{}, page int, offset int) int64 {
	o := orm.NewOrm()
	var analysisAllTest int64
	o.Raw(NeedPageSql(condArr, 0, page, offset)).QueryRow(&analysisAllTest)
	return analysisAllTest
}

func NeedExportExec(condArr map[string]interface{}) (ops []ProjectsPageeNeeds) {
	o := orm.NewOrm()
	var test []ProjectsPageeNeeds
	o.Raw(NeedPageSql(condArr, 1, 1, 100000)).QueryRows(&test)
	return test
}

func NeedPageSql(condArr map[string]interface{}, ifsCount, page int, offset int) (string, []interface{}) {
	var sql string
	if ifsCount == 0 {
		sql = sql + `SELECT count(1) FROM (`
	}
	sql = sql + `
	SELECT
      ppt.needsid  id,
	  ppt.*,
	  up.realname As username,
	  dp.realname As acceptname
	  FROM pms_projects_needs ppt
	  LEFT JOIN pms_users_profile up ON up.userid=ppt.userid
      LEFT JOIN pms_users_profile dp ON dp.userid=ppt.acceptid
	WHERE 1 = 1 `
	param := make([]interface{}, 0, 0)
	if !utils.IsEmpty(condArr["keywords"]) {
		sql = sql + ` and  ppt.name LIKE concat('%',?,'%')`
		param = append(param, condArr["keywords"])
	}
	if !utils.IsEmpty(condArr["acceptid"]) {
		sql = sql + ` and  ppt.acceptid = ?`
		param = append(param, condArr["acceptid"])
	}
	if !utils.IsEmpty(condArr["projectid"]) {
		sql = sql + ` and  ppt.projectid=?`
		param = append(param, condArr["projectid"])
	}
	if !utils.IsEmpty(condArr["status"]) {
		sql = sql + ` and  ppt.status in(`
		sql1, value := cores.SqlInParam(condArr["status"])
		sql = sql + sql1 + `)`
		param = append(param, value...)
	}
	if !utils.IsEmpty(condArr["stage"]) {
		sql = sql + ` and  ppt.stage in(`
		sql1, value := cores.SqlInParam(condArr["stage"])
		sql = sql + sql1 + `)`
		param = append(param, value...)
	}

	if ifsCount == 0 {
		sql = sql + ` ) C`
	} else if ifsCount > 0 {
		if page < 1 {
			page = 1
		}
		if offset < 1 {
			offset, _ = beego.AppConfig.Int("pageoffset")
		}
		start := (page - 1) * offset
		startStr := strconv.Itoa(start)
		offsetStr := strconv.Itoa(offset)
		sql = sql + ` order by created desc LIMIT ` + startStr + `,` + offsetStr
	}
	return sql, param
}

func ChangeProjectNeedsStatus(id int64, status int) error {
	o := orm.NewOrm()
	need := ProjectsNeeds{Id: id}
	err := o.Read(&need, "needsid")
	if nil != err {
		return err
	} else {
		need.Status = status
		_, err := o.Update(&need)
		return err
	}
}

func DeleteNeed(ids int64) error {
	o := orm.NewOrm()
	_, err := o.Raw("DELETE FROM "+models.TableName("projects_needs")+" WHERE needsid =?", ids).Exec()
	return err
}
